package cn.xiaolang.thread.stop;

import java.util.ArrayList;
import java.util.List;

public class ThreadStopByBoolean {

    public static void main(String[] args) throws InterruptedException {
        int num = 5;
        List<WorkerThread> threads = new ArrayList<>(num);
        for (int i = 1; i <= num; i++) {
            threads.add(new WorkerThread(new Calculator(i, i + 10)));
        }
        System.out.println("初始化" + num + "个线程\n");
        for (int i = 1; i <= threads.size(); i++) {
            int time = 1000 * i;
            WorkerThread worker = threads.get(i - 1);
            Thread.sleep(time);
            worker.shutdown();
            System.out.println(time + "ms后，终止线程：" + worker.getName());
        }
    }

    public static class WorkerThread extends Thread {

        // volatile并发可见性，保证同一时刻只有一个线程修改该变量
        private volatile boolean shutdown;

        private final Calculator calculator;

        WorkerThread(Calculator calculator) {
            this.calculator = calculator;
            this.start();
        }

        @Override
        public void run() {
            try {
                while (!shutdown) {
                    synchronized (this) {
                        wait(2000);
                        calculator.add();
                        System.out.println(Thread.currentThread().getName() + ": execute ing...");
                    }
                }
                System.out.println(Thread.currentThread().getName() + ":shutdown !");
            } catch (InterruptedException ex) {
                // 结束
                System.out.println(Thread.currentThread().getName() + ":shutdown !");
            }
        }

        public void shutdown() {
            this.shutdown = true;
            synchronized (this) {
                notifyAll();
            }
        }
    }

    public static class Calculator {

        private int a, b;

        Calculator(int a, int b) {
            super();
            this.a = a;
            this.b = b;
        }

        public int add() {
            return this.a + this.b;
        }
    }

}
